Shader "Examples/07 Simple PBR"
{
    Properties
    {
        _BaseColor("Color", Color) = (1, 1, 1, 1)
        _BaseMap("Base Map", 2D) = "white" {}
        [Space(20)]
        [NoScaleOffset] _BumpMap("Normal Map", 2D) = "bump" {}
        _BumpScale("Bump Scale", Float) = 1.0
        
        [Space(20)]
        [NoScaleOffset] _MixtureMap("MixtureMap  R: Metallic G: Occlusion A: Roughness", 2D) = "white" {}

        _Metallic("Metallic",Range(0,1)) = 0.5
        _Smoothness("Smoothness",Range(0,1)) = 0.5
        _OcclusionStrength("Occlusion Strength", Range(0.0, 1.0)) = 1.0
        
    }
    SubShader
    {
        Tags 
        {
            "RenderPipeline" = "UniversalPipeline"
            "LightMode" = "UniversalForward"
            "Queue" = "Geometry"
        }

        HLSLINCLUDE
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

        
        TEXTURE2D(_BaseMap);        SAMPLER(sampler_BaseMap);
        TEXTURE2D(_BumpMap);        SAMPLER(sampler_BumpMap);
        TEXTURE2D(_MixtureMap);    SAMPLER(sampler_MixtureMap);
        

        CBUFFER_START(UnityPerMaterial)
            half4 _BaseMap_ST;
            half4 _BaseColor;

            half _BumpScale;
            half _Metallic;
            half _Smoothness;
            half _OcclusionStrength;
        CBUFFER_END
        
        ENDHLSL

        pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct a2v
            {
                float4 positionOS   : POSITION;
                float3 normalOS     : NORMAL;
                float4 tangentOS    : TANGENT;
                float2 texcoord     : TEXCOORD;
            };

            struct v2f
            {
                float4 positionCS   : SV_POSITION;
                float3 positionWS   : TEXCOORD0;
                float3 normalWS     : NORMAL;
                float3 tangentWS    : TANGENT;
                float3 bitangentWS  : TEXCOORD1;
                float2 uv           : TEXCOORD2;
            };

            v2f vert(a2v input)
            {
                v2f output;
                VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                output.positionCS = vertexInput.positionCS;
                output.positionWS = vertexInput.positionWS;
                
                VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
                output.normalWS = normalInput.normalWS;
                output.tangentWS = normalInput.tangentWS;
                output.bitangentWS = normalInput.bitangentWS;

                output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap);
                return output;
            }

            
            half4 frag(v2f input):SV_Target
            {
                Light light = GetMainLight();
                half3 normalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, input.uv), _BumpScale);
                half3 normalWS = normalize(TransformTangentToWorld(normalTS, half3x3(input.tangentWS, input.bitangentWS, input.normalWS)));
                
                half3 viewDir = normalize(GetCameraPositionWS() - input.positionWS);
                
                half3 albedo = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).rgb * _BaseColor.rgb;
                half4 metallicMap = SAMPLE_TEXTURE2D(_MixtureMap, sampler_MixtureMap, input.uv);    
                half occlusion = 1.0 - _OcclusionStrength + metallicMap.g * _OcclusionStrength;
                
                half metallic = metallicMap.r * _Metallic;
                half smoothness = metallicMap.a * _Smoothness;
                half specular = 1;
                half alpha = 1;

                BRDFData brdfData;
                InitializeBRDFData(albedo.rgb, metallic, specular, smoothness, alpha, brdfData);

                half3 bakedGI = SampleSH(normalWS);
                half3 color = GlobalIllumination(brdfData, bakedGI, occlusion, normalWS, viewDir);
                color += LightingPhysicallyBased(brdfData, light, normalWS, viewDir);
                return half4(color, alpha);
            }
            ENDHLSL
        }
    }
}
